package cn.bxshey.general.util;

import cn.bxshey.general.constant.JwtConstant;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.mindrot.jbcrypt.BCrypt;

import java.util.*;

/**
 * @作者：不想说话而已
 * @Date：2023/11/28 11:54
 */
public class JwtUtils {

    /**
     * 生成token令牌
     * @param: Map<String ,String> info
     * @return: String token令牌
     */
    public static String createToken(Map<String ,String> info) {

        //集合为空则返回null 必须包含 有  uid  或者 ip
        if(info.size()<1 || Objects.isNull(info.get("ip")) || Objects.isNull(info.get("uid"))){
            return null;
        }

        //加密ip
        String ipPassword = BCrypt.hashpw(info.get("ip"),BCrypt.gensalt());
        info.replace("ip",ipPassword);

        //设置令牌有效时间，默认为7天
        Calendar calendar = Calendar.getInstance();
        if(Objects.nonNull(info.get("tokenTime"))){
            calendar.add(Calendar.DAY_OF_YEAR, Integer.parseInt(info.get("tokenTime")));
        }else {
            calendar.add(Calendar.DAY_OF_YEAR,7);
        }

        JWTCreator.Builder builder = JWT.create();
        //遍历info集合，
        //添加秘钥，返回生成的token
        return builder.withIssuer(JwtConstant.ISS)
                      .withPayload(info) // 添加其他数据信息
                      .withJWTId(UUID.randomUUID().toString()) //jwtID
                      .withExpiresAt(calendar.getTime()) //有效时间
                      .sign(Algorithm.HMAC256(JwtConstant.SECRET_KEY)); //算法，自定义秘钥
    }

    /**
     * @param: 令牌token
     * @return: Map集合
     */
    public static Map<String,Object> checkToken(String token){
        try{
            //设置解密的规则
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(JwtConstant.SECRET_KEY)).build();
            DecodedJWT verify = jwtVerifier.verify(token); //进行token解密
            Map<String,Object> info = new HashMap<>();

            //循环遍历，添加map信息，以此清除两边的双引号
            for (Map.Entry<String,Claim> map : verify.getClaims().entrySet() ) {
                 info.put(map.getKey(), map.getValue().asString());
            }
            return info;//返回解密的信息
        }catch (Exception e){
            System.out.println(e);
         return null;
        }
    }
}
